home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / bin / xkibitz < prev    next >
Text File  |  1995-07-21  |  4KB  |  199 lines

  1. #!/usr/skunk/bin/expect --
  2.  
  3. # share an xterm with other users
  4. # See xkibitz(1) man page for complete info.
  5. # Compare with kibitz.
  6. # Author: Don Libes, NIST
  7. # Version: 1.2
  8.  
  9. proc help {} {
  10.     puts "Commands          Meaning"
  11.     puts "--------          -------"
  12.     puts "return            return to program"        
  13.     puts "=                 list"
  14.     puts "+ <display>       add"
  15.     puts "- <tag>           drop"
  16.     puts "where <display> is an X display name such as nist.gov or nist.gov:0.0"
  17.     puts "and <tag> is a tag from the = command."
  18.     puts "+ and - require whitespace before argument."
  19.     puts {return command must be spelled out ("r", "e", "t", ...).}
  20. }
  21.  
  22. proc prompt1 {} {
  23.     return "xkibitz> "
  24. }
  25.  
  26. proc h {} help
  27. proc ? {} help
  28. proc unknown {args} {
  29.     puts "$args: invalid command"
  30.     help
  31. }
  32.  
  33. set tag2pid(0)            [pid]
  34. set pid2tty([pid])        "/dev/tty"
  35. if [info exists env(DISPLAY)] {
  36.     set pid2display([pid])    $env(DISPLAY)
  37. } else {
  38.     set pid2display([pid])    ""
  39. }
  40.  
  41. # small int allowing user to more easily identify display
  42. # maxtag always points at highest in use
  43. set maxtag 0
  44.  
  45. proc + {display} {
  46.     global ids pid2display pid2tag tag2pid maxtag pid2sid
  47.     global pid2tty env
  48.  
  49.     if ![string match *:* $display] {
  50.         append display :0.0
  51.     }
  52.  
  53.     if {![info exists env(XKIBITZ_XTERM_ARGS)]} {
  54.         set env(XKIBITZ_XTERM_ARGS) ""
  55.     }
  56.  
  57.     set dummy1 [open /dev/null]
  58.     set dummy2 [open /dev/null]
  59.     spawn -pty -noecho
  60.     close $dummy1
  61.     close $dummy2
  62.  
  63.     stty raw -echo < $spawn_out(slave,name)
  64.     regexp ".*(.)(.)" $spawn_out(slave,name) dummy c1 c2
  65.     if {[string compare $c1 "/"] == 0} {
  66.         # On Pyramid and AIX, ttynames such as /dev/pts/1
  67.         # requre suffix to be padded with a 0
  68.         set c1 0
  69.     }
  70.  
  71.     set pid [eval exec xterm \
  72.             -display $display \
  73.             -geometry [stty columns]x[stty rows] \
  74.             -S$c1$c2$spawn_out(slave,fd) \
  75.                         $env(XKIBITZ_XTERM_ARGS) &]
  76.     close -slave
  77.  
  78.     # xterm first sends back window id, discard
  79.     log_user 0
  80.     expect {
  81.         eof {wait;return}
  82.         \n
  83.     }
  84.     log_user 1
  85.  
  86.     lappend ids $spawn_id
  87.     set pid2display($pid) $display
  88.     incr maxtag
  89.     set tag2pid($maxtag) $pid
  90.     set pid2tag($pid) $maxtag
  91.     set pid2sid($pid) $spawn_id
  92.     set pid2tty($pid) $spawn_out(slave,name)
  93.     return
  94. }
  95.  
  96. proc = {} {
  97.     global pid2display tag2pid pid2tty
  98.  
  99.     puts "Tag  Size Display"
  100.     foreach tag [lsort -integer [array names tag2pid]] {
  101.         set pid $tag2pid($tag)
  102.         set tty $pid2tty($pid)
  103.         
  104.         puts [format "%3d [stty columns < $tty]x[stty rows < $tty] $pid2display($pid)" $tag]
  105.     }
  106. }
  107.  
  108. proc - {tag} {
  109.     global tag2pid pid2tag pid2display maxtag ids pid2sid
  110.     global pid2tty
  111.  
  112.     if ![info exists tag2pid($tag)] {
  113.         puts "no such tag"
  114.         return
  115.     }
  116.     if {$tag == 0} {
  117.         puts "cannot drop self"
  118.         return
  119.     }
  120.  
  121.     set pid $tag2pid($tag)
  122.  
  123.     # close and remove spawn_id from list
  124.     set spawn_id $pid2sid($pid)
  125.     set index [lsearch $ids $spawn_id]
  126.     set ids [lreplace $ids $index $index]
  127.  
  128.     exec kill -9 $pid
  129.     close
  130.     wait
  131.  
  132.     unset tag2pid($tag)
  133.     unset pid2tag($pid)
  134.     unset pid2display($pid)
  135.     unset pid2sid($pid)
  136.     unset pid2tty($pid)
  137.  
  138.     # lower maxtag if possible
  139.     while {![info exists tag2pid($maxtag)]} {
  140.         incr maxtag -1
  141.     }
  142. }
  143.  
  144. exit -onexit {
  145.     unset pid2display([pid])    ;# avoid killing self
  146.  
  147.     foreach pid [array names pid2display] {
  148.         catch {exec kill $pid}
  149.     }
  150. }
  151.  
  152. trap {
  153.     set r [stty rows]
  154.     set c [stty columns]
  155.     stty rows $r columns $c < $app_tty
  156.     foreach pid [array names pid2tty] {
  157.         if {$pid == [pid]} continue
  158.         stty rows $r columns $c < $pid2tty($pid)
  159.     }
  160. } WINCH
  161.  
  162. set escape \035        ;# control-right-bracket
  163. set escape_printable "^\]"
  164.  
  165. while [llength $argv]>0 {
  166.     set flag [lindex $argv 0]
  167.     switch -- $flag \
  168.     "-escape" {
  169.         set escape [lindex $argv 1]
  170.         set escape_printable $escape
  171.         set argv [lrange $argv 2 end]
  172.     } "-display" {
  173.         + [lindex $argv 1]
  174.         set argv [lrange $argv 2 end]
  175.     } default {
  176.         break
  177.     }
  178. }
  179.  
  180. if [llength $argv]>0 {
  181.     eval spawn -noecho $argv
  182. } else {
  183.     spawn -noecho $env(SHELL)
  184. }
  185. set prog $spawn_id
  186. set app_tty $spawn_out(slave,name)
  187.  
  188. puts "Escape sequence is $escape_printable"
  189.  
  190. interact {
  191.     -input $user_spawn_id -reset $escape {
  192.         puts "\nfor help enter: ? or h or help"
  193.         interpreter
  194.     } -output $prog
  195.     -input ids -output $prog
  196.     -input $prog -output $user_spawn_id -output ids
  197. }
  198.  
  199.